import axios from 'axios'
import router from '@/router'
import message from 'element-ui'
import BasicSetting from '@/store/BasicSetting'

const qs = require('qs')

const service = axios.create({
  // TODO 待定
  baseURL: process.env.BASE_URL,
  timeout: 10 * 1000 // 超时时间 10s
})

// 是否需要验证 token
const needAuthToken = BasicSetting.needAuthToken

service.interceptors.request.use(config => {
  // 如果需要携带 token
  if (needAuthToken) {
    let token = localStorage.getItem('token')
    if (token) {
      config.headers.token = token // TODO token 命名待定
    } else {
      throw new Error('Token is required.')
    }
  }
  return config
}, error => {
  return Promise.reject(error)
})

service.interceptors.response.use(response => {
  // console.log('response ->', response)
  let status = response.status
  let data = response.data
  if (status === 200) {
    // TODO 服务自定义的状态码判断
    if (response.headers && (response.headers['content-type'] === 'application/x-msdownload' || response.headers['content-type'] === 'application/octet-stream')) {
      let { headers } = response
      let blob = new Blob([response.data], { type: 'application/x-download;charset=UTF-8' })
      let downloadElement = document.createElement('a')
      let href = window.URL.createObjectURL(blob)
      downloadElement.href = href
      let fileName = headers['content-disposition'].split('=')[1]
      fileName = fileName.replaceAll('"', '')
      downloadElement.download = decodeURI(fileName)
      document.body.appendChild(downloadElement)
      downloadElement.click()
      document.body.removeChild(downloadElement)
      window.URL.revokeObjectURL(href)
    }
    return Promise.resolve(data)
  } else {
    return Promise.reject(response)
  }
}, error => {
  let status = error.response.status
  switch (status) {
    case 404:
      message.Message.error('资源未找到！')
      break
    case 500:
      message.Message.error('系统异常！')
      break
    case 403:
      // TODO 存在疑问
      router.replace({
        path: '/login',
        query: {
          redirect: router.currentRoute.fullPath
        }
      })
      break
    // TODO any others
    default:
      break
  }
  return Promise.reject(error)
})

const http = {
  get (url, params) {
    return new Promise((resolve, reject) => {
      service.get(url, { params }).then(res => resolve(res)).catch(err => reject(err))
    })
  },
  get4Download (url, params, resolve) {
    let responseType = 'blob'
    return new Promise((resolve, reject) => {
      service.get(url, { params, responseType }).then(res => resolve(res)).catch(err => reject(err))
    })
  },
  postJson (url, params) {
    return new Promise((resolve, reject) => {
      service.post(url, params, {
        headers: {
          'Content-Type': 'application/json'
        }
      }).then(res => resolve(res)).catch(err => reject(err))
    })
  },
  postForm (url, params) {
    return new Promise((resolve, reject) => {
      service.post(url, qs.stringify(params), {
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        }
      }).then(res => resolve(res)).catch(err => reject(err))
    })
  },
  put (url, params) {
    return new Promise((resolve, reject) => {
      service.put(url, params).then(res => resolve(res)).catch(err => reject(err))
    })
  },
  delete (url, params) {
    return new Promise((resolve, reject) => {
      service.delete(url, { params }).then(res => resolve(res)).catch(err => reject(err))
    })
  }
}

export default http
